﻿﻿using DeviceCommons.DataHandling;
using DeviceCommons.DeviceMessages.Abstractions;
using DeviceCommons.DeviceMessages.Enums;
using DeviceCommons.DeviceMessages.Models.V1;
using DeviceCommons.Exceptions;
using DeviceCommons.Security;
using DeviceCommons.Validation;

namespace DeviceCommons.DeviceMessages.Serialization
{
    public class DeviceMessageParser : AbstractMessageParser<IDeviceMessage>, IDeviceMessageParser, IContextAwareParser
    {
        private ParsingContext? _context;

        public DeviceMessageParser() : base(new DeviceMessage())
        {
        }

        public override IDeviceMessage Parser(ReadOnlySpan<byte> bytes)
        {
            // 前置验证：转换为数组进行验证
            var dataArray = bytes.ToArray();
            DeviceMessageValidator.ValidateMessageData(dataArray, nameof(bytes));
            
            IDeviceMessage model = new DeviceMessage();
            try
            {

                byte[] headerBytes = new byte[4];
                headerBytes = bytes[..4].ToArray();

                model.Header = DeviceMessageSerializerProvider.HeaderPar.Parser(headerBytes);
                if (model.Header == null) throw new InvalidOperationException("未初始化消息头");

                if (model.Header.Header == null ||
                    model.Header.Header.Length != 2 ||
                    model.Header.Header[0] != 0xC0 ||
                    model.Header.Header[1] != 0xBF)
                {
                    throw new InvalidOperationException("协议头错误");
                }

                int crcLength = CrcCalculator.GetCrcLength(model.Header?.CRCType ?? CRCTypeEnum.CRC16);

                if (crcLength > 0)
                {

                    byte[] receivedCrc = bytes.Slice(bytes.Length - crcLength).ToArray();
                    byte[] dataForCrc = bytes[..(bytes.Length - crcLength)].ToArray();

                    byte[] calculatedCrc = CrcCalculator.CalculateCrcBytes(model?.Header?.CRCType ?? CRCTypeEnum.None, dataForCrc);

                    if (!receivedCrc.SequenceEqual(calculatedCrc))
                    {
                        string received = BitConverter.ToString(receivedCrc);
                        string calculated = BitConverter.ToString(calculatedCrc);
                        throw new InvalidMessageException($"CRC validation failed. Expected 0x{calculated}, but received 0x{received}.");
                    }
                }
                IProcessVersion process = model?.Header?.Version switch
                {
                    0x01 => new V1.ProcessVersionData(),
                    0x02 => new V2.ProcessVersionData(),
                    _ => throw new DeviceMessageValidationException(
                        ValidationErrorType.UnsupportedProtocolVersion,
                        $"不支持的协议版本: 0x{model?.Header?.Version:X2}",
                        nameof(model.Header.Version),
                        "0x01 或 0x02",
                        $"0x{model?.Header?.Version:X2}"),
                };

                // 设置上下文到子解析器
                if (_context != null && process is IContextAwareParser contextAwareProcess)
                {
                    contextAwareProcess.SetContext(_context);
                }

                process.Parser(model, bytes[..^crcLength]);
            }
            catch (Exception ex)
            {
                throw new InvalidMessageException("消息解析失败", ex);
            }
            return model;
        }

        public void SetContext(ParsingContext context)
        {
            _context = context;
        }

        public ParsingContext? GetContext()
        {
            return _context;
        }
    }
}
